<?php
/*
 * Author  : top-songshijie
 * Email   : 997031758@qq.com
 * DateTime: 2023/02/22 14:36
 */

namespace SSJ\LaravelHelper\Services\Upload;

use OSS\Core\OssException;
use Illuminate\Support\Str;
use Illuminate\Database\Eloquent\Model;
use SSJ\LaravelHelper\Models\Attachment;
use Illuminate\Database\Eloquent\Builder;
use SSJ\LaravelHelper\Exceptions\UnprocessableEntityException;

abstract class Strategy
{
    protected $bucket;

    protected $endpoint;

    protected $accessKeyId;

    protected $accessKeySecret;

    protected $folder;

    protected $maxSize;

    protected $allowedExt;

    protected $file;

    protected $attachment_type;

    protected $data;

    protected $uploadPath;

    protected $fileName;

    public function __construct($param)
    {
        $this->bucket          = config('alioss.bucket');
        $this->endpoint        = config('alioss.endpoint');
        $this->accessKeyId     = config('alioss.access_key_id');
        $this->accessKeySecret = config('alioss.access_key_secret');

        //接收参数
        $this->file            = $param['file'];
        $this->attachment_type = $param['attachment_type'];
        $this->max_size        = $param['max_size'];
        $this->allowed_ext     = $param['allowed_ext'];

        //图片
        if ($this->attachment_type == Attachment::TYPE_0) {
            $this->folder     = strtolower(config('app.name')) . '/images';
            $this->maxSize    = $param['max_size'] ?: 1024 * 1024 * 50;
            $this->allowedExt = $param['allowed_ext'] ?: [
                'jpg', 'jpeg', 'png', 'gif', 'JPG',
                'JPEG'
            ];
        } else { //文件
            $this->folder     = strtolower(config('app.name')) . '/files';
            $this->maxSize    = $param['max_size'] ?: 1024 * 1024 * 100;
            $this->allowedExt = $param['allowed_ext'] ?: [
                'mp3', 'mp4', 'avi', 'wmv', 'rm',
                'rmvb', 'xls', 'MP3', 'MP4', 'xlsx'
            ];
        }

        //给默认后缀
        if ($this->attachment_type == Attachment::TYPE_0) {
            $ext = empty($this->file->getClientOriginalExtension()) ? 'png' : strtolower($this->file->getClientOriginalExtension());
        } else {
            $ext = empty($this->file->getClientOriginalExtension()) ? 'zip' : strtolower($this->file->getClientOriginalExtension());
        }

        //构造参数
        $this->data = [
            'name'      => $this->file->getClientOriginalName(),
            'mime'      => $this->file->getMimeType(),
            'ext'       => $ext,
            'size'      => filesize($this->file),
            'md5'       => md5_file($this->file),
            'sha1'      => sha1_file($this->file),
            'upload_ip' => request()->getClientIp(),
            'bucket'    => $this->bucket,
            'type'      => $this->attachment_type
        ];

        //验证
        if (!$this->data['upload_ip']) {
            throw new UnprocessableEntityException('无法确认上传者ip地址');
        }
        if (!in_array(Str::lower($this->data['ext']), $this->allowedExt)) {
            throw new UnprocessableEntityException('仅支持以' . implode(',', $this->allowedExt) . '结尾的' . Attachment::$typeMap[$this->attachment_type]);
        }
        if ($this->data['size'] > $this->maxSize) {
            throw new UnprocessableEntityException('请上传小于' . number_format(($this->maxSize / (1024 * 1024)), 2) . 'MB的' . Attachment::$typeMap[$this->attachment_type]);
        }
        //构建文件名及上传路径
        $this->uploadPath = $this->folder . '/' . date('Ymd') . '/';
        $this->fileName   = md5(date('YmdHis')) . '_' . Str::random(10) . '.' . $this->data['ext'];

        //合并到data里面
        $this->data['path'] = $this->uploadPath . $this->fileName;
    }

    abstract public function handle();
}
